package com.baofu.paycore.manager.storer.impl;

import com.baofu.paycore.common.exception.PayCoreBizException;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.baofu.paycore.dal.mapper.PayMapper;
import com.baofu.paycore.dal.mapper.SubPayMapper;
import com.baofu.paycore.manager.converter.BO2DOConverter;
import com.baofu.paycore.manager.converter.DO2BOConverter;
import com.baofu.paycore.manager.model.PayBO;
import com.baofu.paycore.manager.storage.impl.PayManager;
import com.baofu.paycore.manager.storer.AbstractOrderRepository;
import com.baofu.paycore.manager.model.SubPayBO;
import com.baofu.paycore.dal.model.PayDO;
import com.baofu.paycore.dal.model.SubPayDO;
import com.baofu.paycore.dal.model.base.BaseDO;
import com.baofu.paycore.manager.storer.PayOrderRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 消费订单
 *
 * <p/>
 *      1、查询主单信息
 * </p>
 * User: LZQ Date: 2016/04/20  Version: 1.0
 */
@Slf4j
@Repository
public class PayOrderRepositoryImpl extends AbstractOrderRepository<PayBO> implements PayOrderRepository {

    /**
     * 支付存储
     */
    @Autowired
    private PayMapper payMapper;

    /**
     * 支付子单存储
     */
    @Autowired
    private SubPayMapper subPayMapper;

    /**
     * 支付主单管理Manager
     */
    @Autowired
    private PayManager payManager;

    /**
     * 订单转换
     *
     * @param payBO    支付对象
     * @return         转换后DO
     */
    @Override
    protected List<BaseDO> convertToDO(PayBO payBO) {

        List<BaseDO> list = new ArrayList<>();
        //支付主单
        PayDO payDO = BO2DOConverter.payBOToDO(payBO);
        list.add(payDO);
        //付款方资金单
        List<SubPayBO> fundDetails = payBO.getSubPayList();

        for (SubPayBO subPayBO : fundDetails) {
            SubPayDO subPayDO = new SubPayDO();
            BO2DOConverter.subPayBOToDO(subPayBO, subPayDO);
            subPayDO.setPayNo(payBO.getPayNo());
            subPayDO.setCreatedBy(payBO.getOperator());
            subPayDO.setUpdatedBy(payBO.getOperator());
            list.add(subPayDO);
        }
        return list;
    }

    /**
     * 加载并锁定订单
     *
     * @param requestOrderNo   请求订单号
     * @param requestBizNo     请求流水号
     * @return                 支付信息
     */
    @Override
    public PayBO lock(String requestOrderNo, String requestBizNo,String requestSystem) {

        log.debug("支付主单查询锁定请求参数, requestOrderNo:{},requestBizNo:{}",requestOrderNo, requestBizNo);

        //1、查询主单信息
        PayDO payDO = payManager.queryByPayNoForUpdate(requestOrderNo, requestBizNo,requestSystem);

        List<SubPayDO> subPayDOs = subPayMapper.selectByPayNo(payDO.getPayNo());
        if(CollectionUtils.isEmpty(subPayDOs)){
            log.error("查询支付明细信息为空 payNo:{},error:{}", payDO.getPayNo(),PayCoreErrorCode.SUB_ORDER_IS_NOT_EXISTED);
            throw new PayCoreBizException(PayCoreErrorCode.SUB_ORDER_IS_NOT_EXISTED);
        }
        List<SubPayBO> subPayBOs = new ArrayList<>();
        subPayDOs.forEach((subPayBO -> subPayBOs.add(DO2BOConverter.subPayDO2BOConverter(subPayBO))));
        PayBO payBO = DO2BOConverter.payDO2BOConverter(payDO);
        payBO.setSubPayList(subPayBOs);

        log.debug("支付主单信息锁定查询结果, payDO:{}",payBO);

        return payBO;
    }

    /**
     * 加载订单
     *
     * @param payNo 支付单号
     * @return 订单
     */
    @Override
    public PayBO load(String payNo) {

        log.debug("支付订单加载, payNo:{}",payNo);
        PayDO payDO = payMapper.selectByPayNo(payNo);
        if (payDO == null) {
            log.error("查询支付主单信息为空 payNo:{},error:{}", payNo,PayCoreErrorCode.ORDER_IS_NOT_EXISTED);
            throw new PayCoreBizException(PayCoreErrorCode.ORDER_IS_NOT_EXISTED);
        }

        List<SubPayDO> subPayDOs = subPayMapper.selectByPayNo(payNo);
        if(CollectionUtils.isEmpty(subPayDOs)){
            log.error("查询支付明细信息为空 payNo:{},error:{}", payNo,PayCoreErrorCode.SUB_ORDER_IS_NOT_EXISTED);
            throw new PayCoreBizException(PayCoreErrorCode.SUB_ORDER_IS_NOT_EXISTED);
        }
        List<SubPayBO> subPayBOs = new ArrayList<>();
        subPayDOs.forEach((subPayBO -> subPayBOs.add(DO2BOConverter.subPayDO2BOConverter(subPayBO))));
        PayBO payBO = DO2BOConverter.payDO2BOConverter(payDO);
        payBO.setSubPayList(subPayBOs);

        log.debug("支付订单加载结果, payBO:{}",payBO);
        return payBO;
    }

    /**
     * 幂等性校验
     *
     * @param requestBizNo     请求流水号
     * @param requestOrderNo   请求订单号
     * @return                 订单
     */
    @Override
    public PayBO checkIdempotent(String requestBizNo, String requestOrderNo,String requestSystem) {
        PayDO payDO = payMapper.selectByOrderNo(requestOrderNo, requestBizNo, null,requestSystem);
        return DO2BOConverter.payDO2BOConverter(payDO);
    }

}
